package com.agentfactory.teleoreactive.interpreter.mentalstate;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.agentfactory.logic.update.lang.IFormula;
import com.agentfactory.logic.update.lang.Predicate;
import com.agentfactory.logic.update.reasoner.IQueryEngine;
import com.agentfactory.logic.update.reasoner.IQueryable;
import com.agentfactory.logic.update.reasoner.ResolutionBasedQueryEngine;
import com.agentfactory.logic.update.util.DefaultLogicPresenter;
import com.agentfactory.teleoreactive.interpreter.Utilities;

public class ModelTower implements IQueryable {
	private List<Predicate> beliefs;
	private List<Predicate> persistantBeliefs;
	private Map<String, List<Predicate>> beliefMap;
	
	public ModelTower() {
		beliefs = new LinkedList<Predicate>();
		beliefMap = new HashMap<String, List<Predicate>>();
		persistantBeliefs = new LinkedList<Predicate>();
	}
	
	public void addBelief(Predicate belief) {
		List<Predicate> list = beliefMap.get(belief.functor());
		if (list == null) {
			list = new LinkedList<Predicate>();
			list.add(belief);
			beliefMap.put(belief.functor(), list);
		} else {
			for (Predicate bel: list) {
				if (bel.equals(belief)) {
					return;
				}
			}
			list.add(belief);
		}
		//System.out.println(Utilities.presenter.toString(belief));
		beliefs.add(belief);
	}
	
	public void removeBelief(Predicate belief) {
		// TODO check the functionality of this method
		if(beliefs.contains(belief))
			beliefs.remove(belief);
		else if(persistantBeliefs.contains(belief))
			persistantBeliefs.remove(belief);
		beliefMap.get(belief.functor()).remove(belief);
	}

	public boolean hasType(String type) {
		return true;
	}

	public List<IFormula> query(IFormula query) {
    	DefaultLogicPresenter p = new DefaultLogicPresenter();
//     	System.out.println("Queried In the Model Tower "+p.toString(query));

		List<IFormula> list = new LinkedList<IFormula>();
		if (Predicate.class.isInstance(query)) {
			Predicate predicate = (Predicate) query;
			List<Predicate> bels = beliefMap.get(predicate.functor());
			if (bels != null) {
				for (Predicate fos: bels) {
					if (fos.matches(predicate)) {
						list.add(fos);
					}
				}
			}
		}
		return list;
	}
	public void clearTower(){
		beliefs.clear();
		beliefMap.clear();
	}

	public List<String> getBeliefs(){
		List<String> list = new LinkedList<String>(); 
		for (Predicate p : beliefs) {
			list.add(Utilities.presenter.toString(p));
		}
		return list;
	}
}
